#!/usr/bin/env python3
"""
Cryptography依赖诊断脚本
分析cryptography包的版本约束问题和依赖关系
"""

import subprocess
import sys
from typing import Dict, List, Tuple, Any
import json
import re

def run_command(cmd: List[str]) -> Tuple[int, str, str]:
    """运行命令并返回结果"""
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return result.returncode, result.stdout, result.stderr
    except subprocess.TimeoutExpired:
        return -1, "", "命令超时"
    except Exception as e:
        return -1, "", str(e)

def check_cryptography_versions() -> Dict[str, Any]:
    """检查cryptography包的可用版本"""
    print("🔍 检查cryptography包的可用版本...")
    
    # 检查pip index中的版本
    code, stdout, stderr = run_command(["pip", "index", "versions", "cryptography"])
    
    result = {
        "command_success": code == 0,
        "available_versions": [],
        "latest_version": None,
        "current_installed": None
    }
    
    if code == 0:
        # 解析版本信息
        lines = stdout.strip().split('\n')
        for line in lines:
            if "Available versions:" in line:
                # 提取版本号
                versions_part = line.split("Available versions:")[1].strip()
                versions = [v.strip() for v in versions_part.split(',')]
                result["available_versions"] = versions[:10]  # 只取前10个版本
                if versions:
                    result["latest_version"] = versions[0]
                break
    
    # 检查当前安装的版本
    code, stdout, stderr = run_command(["pip", "show", "cryptography"])
    if code == 0:
        for line in stdout.split('\n'):
            if line.startswith('Version:'):
                result["current_installed"] = line.split(':', 1)[1].strip()
                break
    
    return result

def check_dependency_tree() -> Dict[str, Any]:
    """检查哪些包依赖cryptography"""
    print("🔍 检查cryptography的依赖关系...")
    
    # 检查哪些包依赖cryptography
    code, stdout, stderr = run_command(["pip", "show", "cryptography"])
    
    result = {
        "required_by": [],
        "dependencies": []
    }
    
    if code == 0:
        for line in stdout.split('\n'):
            if line.startswith('Required-by:'):
                required_by = line.split(':', 1)[1].strip()
                if required_by:
                    result["required_by"] = [pkg.strip() for pkg in required_by.split(',')]
                break
    
    # 检查cryptography的依赖
    for line in stdout.split('\n'):
        if line.startswith('Requires:'):
            requires = line.split(':', 1)[1].strip()
            if requires:
                result["dependencies"] = [pkg.strip() for pkg in requires.split(',')]
            break
    
    return result

def analyze_version_constraint() -> Dict[str, Any]:
    """分析当前版本约束的问题"""
    print("🔍 分析版本约束问题...")
    
    current_constraint = ">=41.0.8,<42.0.0"
    
    # 检查41.0.8版本是否存在
    code, stdout, stderr = run_command(["pip", "index", "versions", "cryptography"])
    
    result = {
        "current_constraint": current_constraint,
        "constraint_issues": [],
        "suggested_fix": None
    }
    
    if code == 0:
        available_versions = []
        lines = stdout.strip().split('\n')
        for line in lines:
            if "Available versions:" in line:
                versions_part = line.split("Available versions:")[1].strip()
                available_versions = [v.strip() for v in versions_part.split(',')]
                break
        
        # 检查41.0.8是否存在
        if "41.0.8" not in available_versions:
            result["constraint_issues"].append("版本41.0.8不存在")
        
        # 检查41.x系列的最高版本
        v41_versions = [v for v in available_versions if v.startswith('41.')]
        if v41_versions:
            highest_41 = v41_versions[0]  # 已按版本排序
            result["constraint_issues"].append(f"41.x系列最高版本是{highest_41}")
        
        # 检查是否有42.x以上的版本
        newer_versions = [v for v in available_versions if not v.startswith('41.')]
        if newer_versions:
            result["constraint_issues"].append(f"存在更新版本，最新版本是{newer_versions[0]}")
        
        # 建议修复方案
        if available_versions:
            latest = available_versions[0]
            major_version = int(latest.split('.')[0])
            result["suggested_fix"] = f">=41.0.0,<{major_version + 1}.0.0"
    
    return result

def check_passlib_compatibility() -> Dict[str, Any]:
    """检查passlib[bcrypt]对cryptography的依赖要求"""
    print("🔍 检查passlib[bcrypt]的cryptography依赖要求...")
    
    code, stdout, stderr = run_command(["pip", "show", "passlib"])
    
    result = {
        "passlib_installed": code == 0,
        "passlib_version": None,
        "requires_cryptography": False
    }
    
    if code == 0:
        for line in stdout.split('\n'):
            if line.startswith('Version:'):
                result["passlib_version"] = line.split(':', 1)[1].strip()
            elif line.startswith('Requires:'):
                requires = line.split(':', 1)[1].strip()
                if 'cryptography' in requires.lower():
                    result["requires_cryptography"] = True
                break
    
    return result

def main():
    """主函数"""
    print("=" * 60)
    print("🔧 Cryptography依赖诊断报告")
    print("=" * 60)
    
    # 1. 检查版本信息
    version_info = check_cryptography_versions()
    print(f"\n📦 版本信息:")
    print(f"  当前安装版本: {version_info.get('current_installed', '未安装')}")
    print(f"  最新可用版本: {version_info.get('latest_version', '未知')}")
    print(f"  可用版本示例: {', '.join(version_info.get('available_versions', [])[:5])}")
    
    # 2. 检查依赖关系
    dep_info = check_dependency_tree()
    print(f"\n🔗 依赖关系:")
    print(f"  被以下包依赖: {', '.join(dep_info.get('required_by', ['无']))}")
    print(f"  依赖以下包: {', '.join(dep_info.get('dependencies', ['无']))}")
    
    # 3. 分析版本约束问题
    constraint_info = analyze_version_constraint()
    print(f"\n⚠️  版本约束问题:")
    print(f"  当前约束: {constraint_info['current_constraint']}")
    for issue in constraint_info.get('constraint_issues', []):
        print(f"  ❌ {issue}")
    if constraint_info.get('suggested_fix'):
        print(f"  ✅ 建议修复: {constraint_info['suggested_fix']}")
    
    # 4. 检查passlib兼容性
    passlib_info = check_passlib_compatibility()
    print(f"\n🔐 Passlib兼容性:")
    print(f"  Passlib已安装: {passlib_info['passlib_installed']}")
    if passlib_info['passlib_installed']:
        print(f"  Passlib版本: {passlib_info.get('passlib_version', '未知')}")
        print(f"  需要cryptography: {passlib_info['requires_cryptography']}")
    
    # 5. 总结和建议
    print(f"\n📋 诊断总结:")
    
    issues_found = len(constraint_info.get('constraint_issues', []))
    if issues_found > 0:
        print(f"  🔴 发现 {issues_found} 个版本约束问题")
        print(f"  💡 主要问题: 版本约束逻辑错误")
        print(f"  🔧 建议操作: 修复requirements.txt中的cryptography版本约束")
        
        if constraint_info.get('suggested_fix'):
            print(f"  📝 推荐约束: {constraint_info['suggested_fix']}")
    else:
        print(f"  🟢 未发现明显问题")
    
    print("=" * 60)

if __name__ == "__main__":
    main()